﻿#include "RegExp.h"
#include "Tracer.h"
#include <stdlib.h>
#include <regex.h>


/**
 *  \brief  RegExp构造函数
 *  \param  none
 *  \return none
 */
RegExp::RegExp()
{
}

/**
 *  \brief  RegExp析构函数
 *  \param  none
 *  \return none
 */
RegExp::~RegExp()
{
}

/**
 *  \brief  正则表达式匹配
 *  \param  pattern 正则表达式
 *  \param  source 要匹配的字符串
 *  \return 成功返回true,失败返回false
 */
bool RegExp::match(const std::string& pattern,const std::string& source)
{
    std::string str;
    int pos;
    return match(pattern,source,str,pos);
}
/**
 *  \brief  正则表达式匹配
 *  \param  pattern 正则表达式
 *  \param  source 要匹配的字符串
 *  \param  result 匹配结果
 *  \return 成功返回true,失败返回false
 */
bool RegExp::match(const std::string& pattern,const std::string& source,std::string& result,int& pos)
{
    StringArray strArray;
    IntArray posArray;
    result.clear();
    bool ret = match(pattern,source,strArray,posArray,1);
    if (ret)
    {
        result = strArray[0];
        pos = posArray[0];
    }
    return ret;
}
/**
 *  \brief  正则表达式匹配
 *  \param  pattern 正则表达式
 *  \param  source 要匹配的字符串
 *  \param  strArray 匹配结果
 *  \param  posArray 匹配结果对应所在的位置
 *  \param  maxMatches 最多匹配个数
 *  \return 成功返回true,失败返回false
 */
bool RegExp::match(const std::string& pattern, const std::string& source,StringArray & strArray, IntArray & posArray,int maxMatches)
{
    regex_t regex;
    if (maxMatches<=0)
    {
        maxMatches=1;
    }
    if (0!=regcomp(&regex,pattern.c_str(),REG_EXTENDED))
    {
        TRACE_ERR_CLASS("regex compile error!\n");
        return false;
    }
    strArray.clear();
    posArray.clear();
    char* pStr = (char*)source.c_str();
    char* pStart = pStr;
    for(int i=0; i<maxMatches; i++)
    {
        regmatch_t regmatch;
        int ret=regexec(&regex,pStr,1,&regmatch,0);
        if (ret==REG_NOMATCH)
        {
            break;
        }
        else if (ret<0)
        {
            TRACE_ERR_CLASS("regex execute error!\n");                                                                                                                                                    
            break;
        }
        else
        {
            if (regmatch.rm_so!=-1)
            {
                std::string result=std::string(pStr).substr(regmatch.rm_so,regmatch.rm_eo-regmatch.rm_so);
                posArray<<(int)(pStr+regmatch.rm_so-pStart);
                strArray<<result;
                pStr = pStr+regmatch.rm_eo;
            }
            else
            {
                break;
            }
        }
    }
    regfree(&regex);
    return true;
}